<?php

namespace control;
/*
*现金日记账类
*/

class cashBookClass extends adIndexClass
{
    private const page = 'cashBook';
    private const table = 'bookkeeping';
    private const title = '现金日记账';


    /**
     * 生成凭证
     * @return bool|string
     */
    public function voucherEdit(): bool|string
    {
        $listId       = $this->post('listId');
        $listArr      = explode(',', $listId);
        $json['warn'] = '';
        $suc          = 0;
        $text         = '';
        $word         = query('voucher_word', "word = '记' and coid = '" . self::$coid . "'");
        foreach ($listArr as $bookkeepingId) {
            $bookkeeping = query(self::table, "id = '$bookkeepingId'");
            if (empty($bookkeeping['voucherId'])) {
                $voucherNo  = voucherEditClass::voucherNo($word['id'], $bookkeeping['recordDate']);
                $field      = [
                    'recordDate'    => $bookkeeping['recordDate'],
                    'voucherWordId' => $word['id'],
                    'voucherNo'     => $voucherNo,
                    'text'          => $this->post('text'),
                ];
                $annotation = [
                    'recordDate'    => '日期',
                    'voucherWordId' => '凭证字',
                    'voucherNo'     => '凭证号',
                ];
                $rules      = [
                    'recordDate'    => 'required',
                    'voucherWordId' => 'required',
                    'voucherNo'     => 'required|unsigned_int',
                ];
                // 校验是否符合规则
                $vt     = new \verify();
                $result = $vt->setAliases($annotation)->validate($field, $rules)->isOk();
                if ($result === false) {
                    $text .= "日期【{$bookkeeping['recordDate']}】,ID【$bookkeeping[id]】的数据" . $vt->getErrs()[0] . "<br>";  // 多个规则提示最前面一条
                } elseif (checkoutClass::isChecked($field['recordDate'])) {
                    $text .= "日期【{$bookkeeping['recordDate']}】,ID【$bookkeeping[id]】的数据日期所处期间已结账<br>";
                } else {
                    $this->startTrans();
                    $company = query('company', "coid = '" . self::$coid . "'");
                    if ($company['isAudit']) {
                        $field['workFlow'] = '待审核';
                    } else {
                        $field['workFlow'] = '已记账';
                    }
                    $totalMoney   = $bookkeeping['income'] > 0 ? self::yuanToCent($bookkeeping['income']) : self::yuanToCent($bookkeeping['expenses']);
                    $field        = array_merge($field, [
                        'id'          => suiji(),
                        'coid'        => self::$coid,
                        'isTemplate'  => '否',
                        'stid'        => self::$stid,
                        'source'      => '正常',
                        'sourceId'    => $bookkeepingId,
                        'sourceTable' => self::table,
                        'money'       => $totalMoney
                    ]);
                    $json['warn'] = static::insert(["table" => 'voucher', 'de', "field" => $field]);
                    //账户科目
                    $account        = query('account', "id = '$bookkeeping[accountId]'");
                    $accountSubject = query('subject', "id = '$account[subjectId]'");
                    //从凭证配置中查找对方科目
                    $setting        = query('bookkeeping_setting', "classify = '$bookkeeping[classify]' and coid = '" . self::$coid . "'");
                    $voucherSubject = query('subject', "id = '$setting[subjectId]'");
                    if (empty($accountSubject['id'])) {
                        $json['warn'] = "账户未绑定科目，请前往账户绑定科目";
                        $text         .= "日期【{$bookkeeping['recordDate']}】,ID【$bookkeeping[id]】的数据账户未绑定科目，请前往账户绑定科目<br>";
                    } elseif (empty($voucherSubject['id'])) {
                        $json['warn'] = "未进行凭证设置";
                        $text         .= "日期【{$bookkeeping['recordDate']}】,ID【$bookkeeping[id]】的数据未进行凭证设置<br>";
                    } else {
                        $directionOne = '借';
                        $directionTwo = '贷';
                        if ($accountSubject['direction'] == '借' && $bookkeeping['income'] > 0) {
                            //借且收入金额大于0则为借
                            $directionOne = '借';
                            $directionTwo = '贷';
                        } elseif ($accountSubject['direction'] == '借' && $bookkeeping['expenses'] > 0) {
                            //借且支出金额大于0 则为贷
                            $directionOne = '贷';
                            $directionTwo = '借';
                        } elseif ($accountSubject['direction'] == '贷' && $bookkeeping['income'] > 0) {
                            //贷且收入金额大于0 则为贷
                            $directionOne = '贷';
                            $directionTwo = '借';
                        } elseif ($accountSubject['direction'] == '贷' && $bookkeeping['expenses'] > 0) {
                            //贷且支出金额大于0 则为借
                            $directionOne = '借';
                            $directionTwo = '贷';
                        }
                        $collection = [
                            'voucherPrice' => 0,
                            'voucherRate'  => 0,
                            'voucherMoney' => 0,
                        ];
                        $warn       = static::insert(array(
                            'table' => 'voucher_detail',
                            'field' => [
                                'id'           => suiji(),
                                'coid'         => self::$coid,
                                'orderId'      => $field['id'],
                                'summary'      => $bookkeeping['summary'],
                                'subjectId'    => $accountSubject['id'],
                                'subjectName'  => $accountSubject['name'],
                                'subjectCode'  => $accountSubject['code'],
                                'direction'    => $directionOne,
                                'money'        => $bookkeeping['income'] > 0 ? self::yuanToCent($bookkeeping['income']) : self::yuanToCent($bookkeeping['expenses']),
                                'subjectAttr'  => json_encode($collection, 320),
                                'khid'         => '',
                                'supplierId'   => '',
                                'staffId'      => '',
                                'projectId'    => '',
                                'materialId'   => '',
                                'cashId'       => '',
                                'departmentId' => '',
                                'voucherNum'   => 0,
                                'currencyId'   => '',
                                'unit'         => '',
                            ]
                        ));
                        if (!in_array($warn, ["新增成功", "更新成功"])) {
                            $json['warn'] = $warn;
                            $text         .= "日期【{$bookkeeping['recordDate']}】,ID【$bookkeeping[id]】的数据生成凭证明细失败<br>";
                        }
                        $collection = [
                            'voucherPrice' => 0,
                            'voucherRate'  => 0,
                            'voucherMoney' => 0,
                        ];
                        $warn       = static::insert(array(
                            'table' => 'voucher_detail',
                            'field' => [
                                'id'           => suiji(),
                                'coid'         => self::$coid,
                                'orderId'      => $field['id'],
                                'summary'      => $bookkeeping['summary'],
                                'subjectId'    => $voucherSubject['id'],
                                'subjectName'  => $voucherSubject['name'],
                                'subjectCode'  => $voucherSubject['code'],
                                'direction'    => $directionTwo,
                                'money'        => $bookkeeping['income'] > 0 ? self::yuanToCent($bookkeeping['income']) : self::yuanToCent($bookkeeping['expenses']),
                                'subjectAttr'  => json_encode($collection, 320),
                                'khid'         => '',
                                'supplierId'   => '',
                                'staffId'      => '',
                                'projectId'    => '',
                                'materialId'   => '',
                                'cashId'       => '',
                                'departmentId' => '',
                                'voucherNum'   => 0,
                                'currencyId'   => '',
                                'unit'         => '',
                            ]
                        ));
                        if (!in_array($warn, ["新增成功", "更新成功"])) {
                            $json['warn'] = $warn;
                            $text         .= "日期【{$bookkeeping['recordDate']}】,ID【$bookkeeping[id]】的数据生成凭证明细失败<br>";
                        }
                    }
                    $warn = update(array('table' => self::table, 'field' => ['voucherId' => $field['id']], 'where' => "id = '$bookkeeping[id]'"));
                    if ($warn != '更新成功') {
                        $json['warn'] = $warn;
                        $text         .= "日期【{$bookkeeping['recordDate']}】,ID【$bookkeeping[id]】的数据更新凭证ID失败<br>";
                    }
                    if (in_array($json['warn'], ["新增成功", "更新成功"])) {
                        $suc++;
                        $this->commitTrans();
                        $text .= "日期【{$bookkeeping['recordDate']}】,ID【$bookkeeping[id]】的数据生成凭证成功<br>";
                    } else {
                        $this->rollback();
                        $text .= "日期【{$bookkeeping['recordDate']}】,ID【$bookkeeping[id]】的数据生成凭证失败：编辑失败<br>";
                    }
                }
            }
        }
        $this->logText(["type" => self::page, "text" => $text]);
        $json['warn']     = 2;
        $json['href']     = root . "control/adIndex.html?cla=" . self::page . "&fun=home";
        $_SESSION['warn'] = "成功生成了{$suc}个凭证";
        return json_encode($json, 320);
    }

    /**
     * 不合并的凭证
     * @param $listArr
     * @return string
     */
    public function rightContentWithOutMerge($listArr)
    {
        $rightItem   = '';
        $voucherWord = query('voucher_word', "coid = '" . self::$coid . "' and word = '记'");
        foreach ($listArr as $bookkeepingId) {
            $bookkeeping = query(self::table, "id = '$bookkeepingId'");
            if (empty($bookkeeping['voucherId']) && $bookkeeping['state'] == '已通过') {
                $recordMonth                                    = date('Y-m', strtotime($bookkeeping['recordDate']));
                $voucherIndex[$voucherWord['id']][$recordMonth] = $voucherIndex[$voucherWord['id']][$recordMonth] ?? 1;
                //账户科目
                $account        = query('account', "id = '$bookkeeping[accountId]'");
                $accountSubject = query('subject', "id = '$account[subjectId]'");
                //从凭证配置中查找对方科目
                $setting        = query('bookkeeping_setting', "classify = '$bookkeeping[classify]' and type = '现金' and coid = '" . self::$coid . "'");
                $voucherSubject = query('subject', "id = '$setting[subjectId]'");
                $money          = $bookkeeping['income'] != 0 ? $bookkeeping['income'] : $bookkeeping['expenses'];
                $bigMoney       = voucherEditClass::num_to_rmb($money);
                $jieMoney       = $daiMoney = 0;
                if ($accountSubject['direction'] == '借' && $bookkeeping['income'] > 0) {
                    //借且收入金额大于0则为借
                    $bookkeeping['expenses'] = '';
                    $daiMoney                = $money;
                    $jieMoney                = '';
                } elseif ($accountSubject['direction'] == '借' && $bookkeeping['expenses'] > 0) {
                    //借且支出金额大于0 则为贷
                    $bookkeeping['income'] = '';
                    $daiMoney              = '';
                    $jieMoney              = $money;
                } elseif ($accountSubject['direction'] == '贷' && $bookkeeping['income'] > 0) {
                    //贷且收入金额大于0 则为贷
                    $bookkeeping['income'] = '';
                    $daiMoney              = '';
                    $jieMoney              = $money;
                } elseif ($accountSubject['direction'] == '贷' && $bookkeeping['expenses'] > 0) {
                    //贷且支出金额大于0 则为借
                    $bookkeeping['expenses'] = '';
                    $daiMoney                = $money;
                    $jieMoney                = '';
                }

                $voucherNo                                      = voucherEditClass::voucherNo($voucherWord['id'], $bookkeeping['recordDate'], $voucherIndex[$voucherWord['id']][$recordMonth]);
                $voucherIndex[$voucherWord['id']][$recordMonth] += 1;
                $rightItem                                      .= <<<eof
                        <div class="right-box-item">
                            <div class="item-li-no"><span>日期：{$bookkeeping['recordDate']}</span> <span style="margin-left: 20px">凭证字号：记-{$voucherNo}</span> <span style="margin-left: 20px">附件：0</span></div>
                            <div class="item-li-content right-item">
                                <div class="voucher-line">
                                    <div class="voucher-line-summary">{$bookkeeping['summary']}</div>
                                    <div class="voucher-line-subject">{$accountSubject['code']} {$accountSubject['name']}</div>
                                    <div class="voucher-line-jie">$bookkeeping[income]</div>
                                    <div class="voucher-line-dai">$bookkeeping[expenses]</div>
                                </div>
                                <div class="voucher-line">
                                    <div class="voucher-line-summary">{$bookkeeping['summary']}</div>
                                    <div class="voucher-line-subject">{$voucherSubject['code']} {$voucherSubject['name']}</div>
                                    <div class="voucher-line-jie">{$jieMoney}</div>
                                    <div class="voucher-line-dai">{$daiMoney}</div>
                                </div>
                                <div class="voucher-line">
                                    <div class="voucher-line-summary">合  计</div>
                                    <div class="voucher-line-subject">$bigMoney</div>
                                    <div class="voucher-line-jie">$money</div>
                                    <div class="voucher-line-dai">$money</div>
                                </div>
                            </div>
                        </div>
eof;
            }
        }
        return $rightItem;
    }

    /**
     * 判断是否已经存在此科目了
     * @param $data
     * @param $code
     * @return false|int|string
     */
    public static function isSameCodeIn($data, $code)
    {
        foreach ($data as $key => $array) {
            if ($array['subjectCode'] == $code) {
                return $key;
            }
        }
        return false;
    }

    /**
     * 合并凭证
     * @param $listArr
     * @return string
     */
    public function rightContentWithMerge($listArr)
    {
        $mergeSameReceiptsSubject = true;//合并相同收支科目
        $voucherWord              = query('voucher_word', "coid = '" . self::$coid . "' and word = '记'");
        $maxStrtotime             = 0;
        $voucherJieData           = [];
        $voucherDaiData           = [];
        foreach ($listArr as $bookkeepingId) {
            $bookkeeping = query(self::table, "id = '$bookkeepingId'");
            if (empty($bookkeeping['voucherId']) && $bookkeeping['state'] == '已通过') {
                if ($maxStrtotime < strtotime($bookkeeping['recordDate'])) {
                    $maxStrtotime = strtotime($bookkeeping['recordDate']);
                }
                $recordMonth                                    = date('Y-m', strtotime($bookkeeping['recordDate']));
                $voucherIndex[$voucherWord['id']][$recordMonth] = $voucherIndex[$voucherWord['id']][$recordMonth] ?? 1;
                //账户科目
                $account        = query('account', "id = '$bookkeeping[accountId]'");
                $accountSubject = query('subject', "id = '$account[subjectId]'");
                //从凭证配置中查找对方科目
                $setting        = query('bookkeeping_setting', "classify = '$bookkeeping[classify]' and type = '现金' and coid = '" . self::$coid . "'");
                $voucherSubject = query('subject', "id = '$setting[subjectId]'");
                $money          = $bookkeeping['income'] != 0 ? $bookkeeping['income'] : $bookkeeping['expenses'];

                $jieMoney = $daiMoney = 0;
                if ($accountSubject['direction'] == '借' && $bookkeeping['income'] > 0) {
                    //借且收入金额大于0则为借
                    $bookkeeping['expenses'] = '';
                    $daiMoney                = $money;
                    $jieMoney                = '';
                } elseif ($accountSubject['direction'] == '借' && $bookkeeping['expenses'] > 0) {
                    //借且支出金额大于0 则为贷
                    $bookkeeping['income'] = '';
                    $daiMoney              = '';
                    $jieMoney              = $money;
                } elseif ($accountSubject['direction'] == '贷' && $bookkeeping['income'] > 0) {
                    //贷且收入金额大于0 则为贷
                    $bookkeeping['income'] = '';
                    $daiMoney              = '';
                    $jieMoney              = $money;
                } elseif ($accountSubject['direction'] == '贷' && $bookkeeping['expenses'] > 0) {
                    //贷且支出金额大于0 则为借
                    $bookkeeping['expenses'] = '';
                    $daiMoney                = $money;
                    $jieMoney                = '';
                }
                $add = true;
                if ($mergeSameReceiptsSubject) {
                    $key = self::isSameCodeIn($voucherJieData, $accountSubject['code']);
                    if ($key !== false) {
                        $add     = false;
                        $res     = $voucherJieData[$key];
                        $balance = $res['income'] + $bookkeeping['income'] - $bookkeeping['expenses'] - $res['expenses'];
                        if ($balance != 0) {
                            if ($balance > 0) {
                                $bookkeeping['income']   = $balance;
                                $bookkeeping['expenses'] = '';
                                $daiMoney                = $money;
                                $jieMoney                = '';
                            } else {
                                $bookkeeping['expenses'] = $balance;
                                $bookkeeping['income']   = '';
                                $daiMoney                = '';
                                $jieMoney                = $money;
                            }
                            $voucherJieData[$key] = [
                                'summary'     => $res['summary'],
                                'subjectCode' => $res['subjectCode'],
                                'subjectName' => $res['subjectName'],
                                'income'      => $bookkeeping['income'],
                                'expenses'    => $bookkeeping['expenses'],
                            ];
                            $voucherDaiData[]     = [
                                'summary'       => $bookkeeping['summary'],
                                'otherSideCode' => $voucherSubject['code'],
                                'otherSideName' => $voucherSubject['name'],
                                'otherSideJie'  => $jieMoney,
                                'otherSideDai'  => $daiMoney,
                            ];
                        } else {
                            unset($voucherJieData[$key]);
                        }
                    }
                }
                if ($add) {
                    $voucherJieData[] = [
                        'summary'     => $bookkeeping['summary'],
                        'subjectCode' => $accountSubject['code'],
                        'subjectName' => $accountSubject['name'],
                        'income'      => $bookkeeping['income'],
                        'expenses'    => $bookkeeping['expenses'],
                    ];
                    $voucherDaiData[] = [
                        'summary'       => $bookkeeping['summary'],
                        'otherSideCode' => $voucherSubject['code'],
                        'otherSideName' => $voucherSubject['name'],
                        'otherSideJie'  => $jieMoney,
                        'otherSideDai'  => $daiMoney,
                    ];
                }
            }
        }
        $maxDays    = date('t', $maxStrtotime);
        $recordDate = date('Y-m-' . sprintf('%02d', $maxDays), $maxStrtotime);
        $voucherNo  = voucherEditClass::voucherNo($voucherWord['id'], $recordDate);
        $jieItem    = '';
        $money      = 0;
        foreach ($voucherJieData as $array) {
            $money   += $array['income'];
            $jieItem .= <<<eof
                <div class="voucher-line">
                    <div class="voucher-line-summary">{$array['summary']}</div>
                    <div class="voucher-line-subject">{$array['subjectCode']} {$array['subjectName']}</div>
                    <div class="voucher-line-jie">$array[income]</div>
                    <div class="voucher-line-dai">$array[expenses]</div>
                </div>
eof;
        }
        $daiItem = '';
        foreach ($voucherDaiData as $array) {
            $money   += $array['otherSideJie'];
            $daiItem .= <<<eof
                 <div class="voucher-line">
                                    <div class="voucher-line-summary">{$array['summary']}</div>
                                    <div class="voucher-line-subject">{$array['otherSideCode']} {$array['otherSideName']}</div>
                                    <div class="voucher-line-jie">{$array['otherSideJie']}</div>
                                    <div class="voucher-line-dai">{$array['otherSideDai']}</div>
                                </div>
eof;
        }
        $bigMoney = voucherEditClass::num_to_rmb($money);
        return <<<eof
                        <div class="right-box-item">
                            <div class="item-li-no"><span>日期：{$recordDate}</span> <span style="margin-left: 20px">凭证字号：记-{$voucherNo}</span> <span style="margin-left: 20px">附件：0</span></div>
                            <div class="item-li-content right-item">
                                $jieItem
                                $daiItem
                                <div class="voucher-line">
                                    <div class="voucher-line-summary">合  计</div>
                                    <div class="voucher-line-subject">$bigMoney</div>
                                    <div class="voucher-line-jie">$money</div>
                                    <div class="voucher-line-dai">$money</div>
                                </div>
                            </div>
                        </div>
eof;
    }

    /**
     * 生成凭证页面
     */
    public function generateVoucher(): string
    {
        $listId  = $this->get('listId');
        $listArr = explode(',', $listId);
        $lefItem = '';

        $voucherWord = query('voucher_word', "coid = '" . self::$coid . "' and word = '记'");
        foreach ($listArr as $bookkeepingId) {
            $bookkeeping = query(self::table, "id = '$bookkeepingId'");
            if (empty($bookkeeping['voucherId']) && $bookkeeping['state'] == '已通过') {
                $recordMonth                                    = date('Y-m', strtotime($bookkeeping['recordDate']));
                $voucherIndex[$voucherWord['id']][$recordMonth] = $voucherIndex[$voucherWord['id']][$recordMonth] ?? 1;
                $direction                                      = $bookkeeping['income'] > 0 ? "收入：{$bookkeeping['income']}" : "支出：{$bookkeeping['expenses']}";
                $lefItem                                        .= <<<eof
                        <div class="left-box-item">
                            <div class="item-li-no">单据编号：$bookkeeping[orderNo]</div>
                            <div class="item-li-content">
                                <div>日期：{$bookkeeping['recordDate']}</div>
                                <div>收支类型：{$bookkeeping['classify']}</div>
                                <div>摘要：{$bookkeeping['summary']}</div>
                                <div>$direction</div>
                            </div>
                        </div>
eof;
                //账户科目
                $account        = query('account', "id = '$bookkeeping[accountId]'");
                $accountSubject = query('subject', "id = '$account[subjectId]'");
                //从凭证配置中查找对方科目
                if ($accountSubject['direction'] == '借' && $bookkeeping['income'] > 0) {
                    //借且收入金额大于0则为借
                    $bookkeeping['expenses'] = '';
                } elseif ($accountSubject['direction'] == '借' && $bookkeeping['expenses'] > 0) {
                    //借且支出金额大于0 则为贷
                    $bookkeeping['income'] = '';
                } elseif ($accountSubject['direction'] == '贷' && $bookkeeping['income'] > 0) {
                    //贷且收入金额大于0 则为贷
                    $bookkeeping['income'] = '';
                } elseif ($accountSubject['direction'] == '贷' && $bookkeeping['expenses'] > 0) {
                    //贷且支出金额大于0 则为借
                    $bookkeeping['expenses'] = '';
                }
                $voucherIndex[$voucherWord['id']][$recordMonth] += 1;
            }
        }
        $rightItem       = $this->rightContentWithOutMerge($listArr);
        $mergeVoucherTip = componentClass::tipComponent('将合并相同的科目');
        $data['html']    = <<<efo
        <form name="voucherForm">
        <div class="voucher-body">
            <div class="voucher-title">现金日记账</div>
            <div class="calendarBody">
                <div class="voucher-button">
                    <span class="spanButton li-btn-blue-bg" style="margin-left: 0" onclick="subForm('voucherForm',root+'control/adIndex.html?cla=cashBook&fun=voucherEdit')">保存</span>
                    <span class="spanButton" onclick="newIframe('现金日记账',root+'control/adIndex.html?cla=cashBook&fun=home')">取消</span>
<!--                    <span style="margin-left: 20px"><label class='checkbox'><input name='mergeVoucher' onclick="mergeVoucher(this)" type='checkbox'  value='1'><span></span>&nbsp;合并生成凭证</label></span>-->
                </div>
                <div class="input-div bold">
                    <div>日记账</div>
                    <div>凭证预览</div>
                </div>
                <div class="content-box">
                    <div class="left-content-box">
                        $lefItem
                    </div>
                    <div class="right-content-box">
                        $rightItem
                    </div>
                </div>
            </div>
        </div>
        <input name="listId" type="hidden" value="$listId">
        </form>
<script>
function mergeVoucher(e) {
   
}
</script>
efo;
        $bankObj         = new bankBookClass();
        $data['html']    .= $bankObj->voucherCass();
        //返回
        return $this->tab($data);
    }


    public function setAccount(): bool|string
    {
        $accountId = $this->post('accountId');
        if (empty($accountId)) {
            $json['warn'] = '请选择账户';
        } else {
            $json['warn'] = 2;
            $this->setAccountRedis($accountId);
        }
        return json_encode($json, 320);
    }

    /*列表页-查询条件*/
    public function homeOptions($isAsync = true)
    {
        //生成查询表单
        $html = $this->tableShow([
            [
                [
                    "票据号" => text(array("name" => "billNo")),
                    "往来单位"   => text(array("name" => "company")),
                    "摘要"   => text(array("name" => "summary")),
                ],
                [
                    "备注"   => text(array("name" => "text")),
                    '结算方式' => select(array("name" => "settleType", 'option' => explode('，', para('supplierSettlement')))),
                    '收支类别'  => select(array("name" => "classify", 'option' => explode('，', para('cashClassify')))),
                ],
                [
                    "日期" => text(array("name" => "createTime", 'laydate' => ['type' => 'date', 'range' => '~'])),
                ]
            ]
        ],1). <<<eof
<script>
function setAccount(e){
    $.post(root+'control/adIndex.html?cla=cashBook&fun=setAccount',{accountId:e.value},function(res) {
        if (res.warn==2){
            location.reload();
        }else{
            msg(res.warn,'error')
        }
    },'json')
}
</script>
eof;
        //返回
        if (!$isAsync) {
            return $html;
        } else {
            return json_encode(['html' => $html], 320);
        }
    }

    /*列表-查询条件*/
    public function home()
    {
        $accountId = $this->getAccountRedis();
        $html = $this->homeOptions(false);
        //控件
        $button = "";
        if ($this->power(self::page, "edit")) {
            $button .= "<span class='spanButton li-btn-blue-bg setting-parent'><span onclick=\"voucher()\">生成凭证</span><img onclick=\"showState()\" src='" . root . "img/control/down.svg' /><div class='stateBlock' ><ul><li>凭证配置</li></ul></div></span>\n";
        }
        if (optionSettingClass::getSettingItem('往来账/出纳', 'cashAndBankAudit') && $this->power(self::page, "audit")) {
            $button .= "<span class='spanButton' onclick=\"layer('{$this->get('cla')}', 'audit', {})\">审核</span>\n";
        }
        if ($this->power(self::page, 'import')) {
            $button .="<span class='spanButton' onclick=\"layer('importTemplate','importFrame',{cla:'".self::page."'})\">导入</span>";
        }
        if ($this->power(self::page, "export")) {
            $button .= "  <a href='" . root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=exportData'><span class='spanButton'>导出</span></a>\n";
        }
        if ($this->power(self::page, "del")) {
            $button .= "<span class='spanButton' onclick=\"layer('{$this->get('cla')}', 'operate', {'act': 'del'})\">删除</span>\n";
        }
        $button .= "<form name='accountForm' style='display: inline-block'>
                <select name='accountId' style='margin-left: 8px' class='select' onchange='setAccount(this)'>" .
        idSelect(array('name' => 'accountId', 'type' => 'option', 'sqlId' => 'id', 'sqlField' => 'name', 'sqlForm' => "account where coid = '" . self::$coid . "' and type='现金'", 'value' => $accountId)) .
        "</select>
            </form>";
        //返回
        return $this->homeFun($this->search($html, layout: 'pop', toolButton: $button));
    }

    private function setAccountRedis($accountId)
    {
        static::rSet(self::page . self::$stid . self::$coid . 'accountId', $accountId);
    }

    private function getAccountRedis()
    {
        return static::rGet(self::page . self::$stid . self::$coid . 'accountId');
    }

    /**
     * 字段初始化
     */
    public function fieldInit($fun): array
    {
        switch ($fun) {
            default:
                $tr = [
                    'recordDate'    => [
                        'name'  => "日期",
                        'width' => 150,
                        'sort'  => 1,
                    ],
                    'summary'       => [
                        'name'  => '摘要',
                        'width' => 300,
                    ],
                    'classify'      => [
                        'name'  => '收支类别',
                        'width' => 150,
                    ],
                    'settleType'    => [
                        'name'  => '结算方式',
                        'width' => 150,
                    ],
                    'company'       => [
                        'name'  => '往来单位',
                        'width' => 300,
                    ],
                    'billNo'        => [
                        'name'  => '票据号',
                        'width' => 200,
                        'sort'  => 1,
                    ],
                    'text'          => [
                        'name'  => '备注',
                        'width' => 200,
                    ],
                    'income'        => [
                        'name'  => '收入（借方）',
                        'width' => 150,
                        'sort'  => 1,
                    ],
                    'expenses'      => [
                        'name'  => '支出（贷方）',
                        'width' => 150,
                        'sort'  => 1,
                    ],
                    'balance'       => [
                        'name'  => '余额',
                        'width' => 150,
                    ],
                    'voucherButton' => [
                        'name'  => '关联凭证',
                        'width' => 150,
                    ],
                    'state'         => [
                        'name'  => '状态',
                        'width' => 150,
                    ]
                ];
        }
        return $tr;
    }

    /*客户列表-查询结果*/
    public function homeSearch()
    {
        $accountId = $this->getAccountRedis();
        if (empty($accountId)) {
            $account   = query('account', "type = '现金' and coid = '" . self::$coid . "' order by time asc");
            $accountId = $account['id'];
            $this->setAccountRedis($accountId);
        }
        //like查询数组
        $like = array(
            "billNo"  => $this->post('billNo'),
            "company" => $this->post('company'),
            "summary" => $this->post('summary'),
            "text"    => $this->post('text'),
        );
        //全等查询数组
        $equal = array(
            "settleType" => $this->post('settleType'),
            "coid"       => self::$coid,
            "classify"   => $this->post('classify'),
            "accountId"  => $accountId,
            'type'       => '现金',
        );
        $and   = "";
        if ($this->post('createTime')) {
            $and .= self::timeComparison($this->post('createTime'), field: 'recordDate');
        }
        //排序
        $orderBy = $this->listSort(array(
            "search" => $this->post('list_sort_key') ?: 'recordDate desc,list',
            "sort"   => $this->post('list_sort') ?: "desc",
            "array"  => array(),
        ));
        //获取查询结果
        $where = search(array("like" => $like, "=" => $equal)) . $and;
        $page  = $this->page(array("table" => self::table, "where" => $where, "order" => $orderBy['orderBy']));
        static::rSet(self::$stid . self::page . 'sql', $page['fullSql']);
        //获取自定义字段参数
        $installSearch = $this->installSearch();
        $body          = [];
        //表格控件区
        $liButton = array(
            $this->checkAll("listForm", "listId")
        );
        //第一行，特殊处理
        $first      = array(
            'recordDate'    => text(array('name' => 'recordDate', 'class' => 'text width100', 'value' => $this->date, 'other' => "data-type='recordDate'", 'laydate' => ['done' => "function(e){ $('[name=recordDate]').val(e);insertOne($('[name=recordDate]'))}"])),
            'summary'       => text(array('name' => 'summary', 'class' => 'text', 'id' => "summary", 'blur' => 'insertOne', 'other' => "data-type='summary'",)),
            'classify'      => select(array("name" => "classify", 'class' => 'select', 'change' => 'insertOne', 'other' => "data-type='classify'", "title" => "请选择", 'option' => explode('，', para('cashClassify')))),
            'settleType'    => select(array("name" => "settleType", 'class' => 'select', 'change' => 'insertOne', 'other' => "data-type='settleType'", "title" => "请选择", 'option' => explode('，', para('supplierSettlement')))),
            'company'       => text(array('name' => 'company', 'blur' => 'insertOne', 'other' => "data-type='company'", 'class' => 'text width200', 'id' => 'company')),
            'billNo'        => text(array('name' => 'billNo', 'class' => 'text width150', 'other' => "data-type='billNo'",)),
            'text'          => text(array('name' => 'text', 'class' => 'text width150')),
            'income'        => text(array('name' => 'income', 'blur' => 'insertOne', 'other' => "data-type='income'", 'class' => 'text width100', 'type' => 'number')),
            'expenses'      => text(array('name' => 'expenses', 'blur' => 'insertOne', 'other' => "data-type='expenses'", 'class' => 'text width100', 'type' => 'number')),
            'balance'       => "<span id='balance'></span>",
            'voucherButton' => "",
            'state'         => ""
        );
        $liButton[] = "";
        //本行初始化
        $row = [];
        foreach ($installSearch['key'] as $key) {
            switch ($key) {
                default:
                    $row[] = isset($first[$key]) && $first[$key] ? $first[$key] : '';
            }
        }
        $body[] = $row;

        foreach ($page['array'] as $array) {
            //列表控件
            $dominate = array(
                "box"  => array("name" => "listId", "value" => $array['id']),
                "edit" => array("title" => "编辑", "click" => "layer('" . self::page . "','edit',{id:'" . $array['id'] . "'})"),
            );
            if ($array['classify'] == '内部转账') {
                unset($dominate['edit']);
            }
            $liButton[] = $this->dominate($dominate);
            //本行初始化
            $row = [];
            foreach ($installSearch['key'] as $key) {
                switch ($key) {
                    case 'balance':
                        $account = query('account', "id = '$array[accountId]'");
                        $balance = find(array('table' => self::table, 'single' => "accountId = '$array[accountId]' and recordDate <='$array[recordDate]' and list <= $array[list]", 'field' => "ifnull(sum(income-expenses),0) as money"))['money'];
                        $balance += $account['initMoney'];
                        $row[]   = round($balance, 2);
                        break;
                    case 'voucherButton':
                        $voucher       = query('voucher', "id = '$array[voucherId]'");
                        $voucherWord   = query('voucher_word', "id = '$voucher[voucherWordId]'");
                        $voucherButton = '';
                        if (!empty($voucher['id'])) {
                            unset($dominate['edit']);
                            $voucherButton = componentClass::urlTitle($voucherWord['word'] . '-' . $voucher['voucherNo'], root . 'control/adIndex.html?cla=voucherEdit&fun=home&id=' . $array['voucherId'], '录凭证');
                        }
                        $row[] = $voucherButton;
                        break;
                    default:
                        $row[] = isset($array[$key]) && $array[$key] ? $array[$key] : '';
                }
            }
            $body[] = $row;
        }
        //控件
        $button = "";
        //合计金额
        $income   = find(array('table' => self::table, 'single' => "accountId = '$accountId'" . $where, 'field' => "ifnull(sum(income),0) as income"))['income'];
        $expenses = find(array('table' => self::table, 'single' => "accountId = '$accountId'" . $where, 'field' => "ifnull(sum(expenses),0) as expenses"))['expenses'];
        $total    = [
            'income'   => $income,
            'expenses' => $expenses,
        ];
        //生成页面
        $li = $this->li(array(
            "body"        => $body,
            "install"     => $installSearch,
            "button"      => array("html" => $liButton),
            "orderBySign" => $orderBy,
            "page"        => $page['para'],
            "total"       => $total,
        ));
        //返回
        $json['html'] =
            $page['hint'] .
            $button .
            "<form name='listForm'>" .
            $li .
            "</form>" .
            $this->js() .
            self::settingCss() .
            $page['button'] .
            clear;
        return json_encode($json, 320);
    }

    /**
     * 审核
     */
    public function audit(): bool|string
    {
        //生成表单
        $html = $this->layerEdit(array("table" => array(
            array(
                "提示：" => "是否修改所选单据状态为已通过？",
            ),
        )));
        //返回
        return $this->layer(array("title" => "审核", "height" => 165, "html" => $html, 'formTwo'                           => 'listForm'));
    }

    /**
     * 审核
     */
    public function auditEdit(): bool|string
    {
        $idArr = $this->post('listId');
        if (!$this->power(self::page, "audit")) {
            $json['warn'] = "你没有" . self::title . "的审核权限";
        } elseif (empty($idArr) || !is_array($idArr)) {
            $json['warn'] = "请选择数据";
        } else {
            $field        = [
                'auditStid' => self::$stid,
                'auditTime' => $this->time,
                'state'     => '已通过',
            ];
            $json['warn'] = update(array('table' => self::table, 'field' => $field, 'where' => " id in ('" . implode("','", $idArr) . "') and state = '草稿'"));
            if (in_array($json['warn'], ["新增成功", "更新成功"])) {
                //添加日志
                $type = mb_substr($json['warn'], 0, 2, 'utf-8');
                $text = $this->control['name'] . $type . "了" . self::title . "的状态为已通过， id：【" . implode(",", $idArr) . '】';
                $this->logText(["type" => self::page, "text" => $text]);
                //返回
                $_SESSION['warn'] = $json['warn'];
                $json['warn']     = 2;
            }
        }
        //返回
        return json_encode($json, 320);
    }

    /**
     * 编辑
     * @return false|string
     */
    public function edit()
    {
        $info = query(self::table, "id = '" . $this->post('id') . "'");
        //生成表单
        $html = $this->layerEdit(array("table" => array(
            array(
                must . "日期：" => text(array("name" => "recordDate", 'laydate' => [], "value" => $info['recordDate'])),
                must . "摘要：" => text(array("name" => "summary", "value" => $info['summary']))
            ),
            array(
                "收支类别：" => select(array("name" => "classify", 'value' => $info['classify'], "title" => "请选择", 'option' => explode('，', para('cashClassify')))),
                "结算方式：" => select(array("name" => "settleType", 'value' => $info['settleType'], "title" => "请选择", 'option' => explode('，', para('supplierSettlement')))),
            ),
            array(
                "往来单位：" => text(array("name" => "company", "value" => $info['company'])),
                "票据号：" => text(array("name" => "billNo", "value" => $info['billNo']))
            ),
            array(
                "收入（借方）：" => text(array("name" => "income", "value" => $info['income'])),
                "支出（贷方）：" => text(array("name" => "expenses", "value" => $info['expenses']))
            ),
            array(
                "备注：" => text(array("name" => "text", "value" => $info['text']))
            ),
        )
        ));
        //返回
        return $this->layer(array("title" => "编辑", "height" => 400, "width" => 800, "html" => $html));
    }


    public function getSummary(): bool|string
    {
        $val          = $this->post('keyword');//关键词
        $json['data'] = [];
        $where        = "coid='" . self::$coid . "' and type = '现金'";
        $where1       = "coid = '" . self::$coid . "'";
        if ($val) {
            $where .= " and summary like '%$val%'";
        }
        $res = find(array('table' => 'bookkeeping', 'field' => "distinct summary", 'where' => $where . " order by any_value(recordDate) desc,any_value(list) desc limit 40"));
        foreach ($res['array'] as $val) {
            $json['data'][] = array('title' => $val['summary']);
        }

        $json['warn'] = 2;
        return json_encode($json, 320);
    }

    public static function settingCss()
    {
        return <<<eof
<style>
.setting-parent{position: relative;padding-right: 20px;overflow: unset}
.setting-parent>img{position: absolute;right: 1px;top: 3px}
</style>
eof;

    }


    /**
     * JS
     * @return string
     */
    private function js()
    {
        return <<<eof
<style>
.height28{
  height: 28px;
}
</style>
<script>
function voucher(){
    let arr = [];
    $("[name='listForm'] input[type=checkbox]:checked").each(function () {
        if ($(this).val() && $(this).val() !== 'on') {
            arr.push($(this).val());
        }
    });
    if (arr.length > 0) {
        let vals = arr.join(",");
        newIframe('现金日记账',root+'control/adIndex.html?cla=cashBook&fun=generateVoucher&listId='+vals)
    } else {
        msg('请选择需要数据','error');
    }
}
$("#summary").bigAutocomplete({
    url:root + 'control/adIndex.html?cla=cashBook&fun=getSummary',
    callback:function(data,e){
}}) 
$("#company").bigAutocomplete({
    url:root + 'control/adIndex.html?cla=bankBook&fun=getCompany',
    callback:function(data,e){
        insertOne(e)
}})
$(".stateBlock li").click(function (){
    newIframe('凭证配置',root+'control/adIndex.html?cla=cashBook&fun=setting')
});
function insertOne(e){
    let classify = $("[name='listForm'] [name='classify']").val();
    let income = $("[name='listForm'] [name='income']").val();
    let expenses = $("[name='listForm'] [name='expenses']").val();
    // let company = $("[name='listForm'] [name='company']").val();
    // let settleType = $("[name='listForm'] [name='settleType']").val();
    let summary = $("[name='listForm'] [name='summary']").val();
    let recordDate = $("[name='listForm'] [name='recordDate']").val();
    if(classify.indexOf("收-") >= 0 && expenses) { 
        //收入
        msg('收支类型和金额不匹配','error')
        return false;
    }
    if(classify.indexOf("支-") >= 0 && income){
        //支出
         msg('收支类型和金额不匹配','error')
         return false;
    }
    if (classify && summary && recordDate && (income || expenses)){
        subForm('accountForm,listForm',root+'control/adIndex.html?cla=cashBook&fun=editEdit');
    }
}
</script>
eof;

    }


    public function editEdit()
    {
        $id         = $this->post('id') ?: self::getId();
        $field      = [
            'accountId'  => $this->getAccountRedis(),
            'classify'   => $this->post('classify'),
            'recordDate' => $this->post('recordDate'),
            'company'    => $this->post('company'),
            'summary'    => $this->post('summary'),
            'income'     => $this->post('income'),
            'expenses'   => $this->post('expenses'),
            'settleType' => $this->post('settleType'),
            'billNo'     => $this->post('billNo'),
            'text'       => $this->post('text'),
        ];
        $annotation = [
            'accountId'  => '账户',
            'classify'   => '收支类别',
            'recordDate' => '日期',
            'summary'    => '摘要',
        ];
        $rules      = [
            'accountId'  => 'required',
            'classify'   => 'required',
            'recordDate' => 'required',
            'summary'    => 'required',
        ];
        // 校验是否符合规则
        $vt     = new \verify();
        $result = $vt->setAliases($annotation)->validate($field, $rules)->isOk();
        if ($result === false) {
            $json['warn'] = $vt->getErrs()[0];  // 多个规则提示最前面一条
            goto resp;
        }
        //判断
        if (!$this->power(self::page, "edit")) {
            $json['warn'] = "你没有编辑" . self::title . "的权限";
        } elseif (checkoutClass::isChecked($field['recordDate'])) {
            $json['warn'] = '此日期处于已结账期间，不能编辑';
        } elseif (empty($field['income']) && empty($field['expenses'])) {
            $json['warn'] = '请填写金额';
        } elseif (str_contains($field['classify'], '收-') && !empty($field['expenses']) && $field['expenses'] != '0') {
            $json['warn'] = '收支类型和金额不匹配';
        } elseif (str_contains($field['classify'], '支-') && !empty($field['income']) && $field['income'] != '0') {
            $json['warn'] = '收支类型和金额不匹配';
        } else {
            $where = " id = '$id' ";
            $info  = query(self::table, $where);
            if (!$info['id']) {
                $userNo       = codeTemplateClass::generateCode(self::page, [
                    'prefix' => date('Ymd'),
                    'table'  => self::table,
                    'field'  => 'orderNo',
                    'where'  => '',
                ], $field);
                $field        = array_merge($field, [
                    'id'      => $id,
                    'orderNo' => $userNo,
                    'type'    => '现金',
                    'coid'    => self::$coid,
                    'stid'    => $this->control['stid'],
                    'state'   => optionSettingClass::getSettingItem('往来账/出纳', 'cashAndBankAudit') ? '草稿' : '已通过'
                ]);
                $json['warn'] = static::insert(["table" => self::table, "field" => $field]);
            } else {
                $json['warn'] = static::update([
                    "table" => self::table,
                    "field" => $field,
                    "where" => $where
                ]);
            }
            if (in_array($json['warn'], ["新增成功", "更新成功"])) {
                //添加日志
                $type = mb_substr($json['warn'], 0, 2, 'utf-8');
                $text = $this->control['name'] . $type . "了" . self::title . " id：【" . $id . '】';
                $this->logText(["type" => self::page, "text" => $text]);
                //返回
                $_SESSION['warn'] = $json['warn'];
                $json['warn']     = 2;
            }
        }

        resp:
        return json_encode($json, 320);
    }

    /*列表页-查询条件*/
    public function settingOptions($isAsync = true)
    {
        //生成查询表单
        $html = $this->tableShow([
            [
                [
                    "分类" => repeatSelect(array('name' => 'category', 'sqlForm' => "bookkeeping_setting where coid = '" . self::$coid . "' and type = '现金'", 'sqlField' => 'category')),
                    "收支类别"   => select(array("name" => "classify", 'option' => explode('，', para('cashClassify')))),
                    '收支方向' => select(array('option' => ['收入', '支出'], 'name' => 'direction')),
                ]
            ]
        ],1);
        //返回
        if (!$isAsync) {
            return $html;
        } else {
            return json_encode(['html' => $html], 320);
        }
    }

    /**
     * 凭证配置
     * @return bool|string
     */
    public function setting()
    {
        $html = $this->settingOptions(false);
        $button = "<span class='spanButton li-btn-blue-bg' onclick=\"iframeReturnClose()\">返回</span>";
        if ($this->power(self::page, "edit")) {
            $button .= "<span class='spanButton' onclick=\"layer('" . self::page . "','settingPage',{id:'" . suiji() . "'})\">新增</span>";
        }
        if ($this->power(self::page, "del")) {
            $button .= "<span class='spanButton' onclick=\"layer('{$this->get('cla')}', 'operate', {'act': 'delSetting'})\">删除</span>\n";
        }
        //返回
        return $this->homeFun($this->search($html, layout: 'pop', toolButton: $button));
    }

    public function settingSearch(): bool|string
    {
        //like查询数组
        $like = array();
        //全等查询数组
        $equal = [
            'coid'      => self::$coid,
            "category"  => $this->post('category'),
            "classify"  => $this->post('classify'),
            "direction" => $this->post('direction'),
            'type'      => '现金',
        ];
        $where = search(array("like" => $like, "=" => $equal));
        $page  = $this->page([
            "table" => "bookkeeping_setting",
            "where" => $where,
            "order" => "`updateTime` desc",
        ]);
        //获取表头
        $checkAll = $this->checkAll("visitForm", "listId");
        //获取表头
        $tr[] = [$checkAll, '分类', '收支类别', '收支方向', '对方科目'];
        //获取记录
        foreach ($page['array'] as $array) {
            //列表控件
            $dominate = array(
                "box"  => array("name" => "listId", "value" => $array['id']),
                "edit" => array("title" => "编辑", "click" => "layer('" . self::page . "','settingPage',{id:'" . $array['id'] . "'})"),
            );
            $subject  = query('subject', "id = '$array[subjectId]'");
            $tr[]     = array(
                $this->dominate($dominate),
                $array['category'],
                $array['classify'],
                $array['direction'],
                $subject['code'] . $subject['name']
            );
        }
        $button = "";
        //控件
        $json['html'] = $page['hint'] . $button . "<form name='visitForm'>" . $this->tableMany(array("tr" => $tr)) . "</form>" . $page['button'];
        return json_encode($json, 320);
    }

    public function settingPage()
    {
        $info = query('bookkeeping_setting', " id = '{$this->post('id')}'");
        //生成表单
        $html = $this->layerEdit(array("table" => array(
            array(
                must . "分类：" => repeatSelect(array('name' => 'categorySelect', 'sqlForm' => "bookkeeping_setting where coid = '" . self::$coid . "' and type = '现金'", 'sqlField' => 'category', 'change' => 'selectGetText')) . text(array("name" => "category", "value" => $info['category'])),
            ),
            array(
                must . "收支类别：" => select(array("name" => "classify", "title" => "收支类别", 'value' => $info['classify'], 'option' => explode('，', para('cashClassify')))),
            ),
            array(
                must . "对方科目：" => componentClass::subjectSelect($info['subjectId']),
            ),
        )));
        //返回
        return $this->layer(array("title" => "凭证配置", "height" => 300, "width" => 600, "html" => $html));
    }

    public function settingPageEdit()
    {
        $id         = $this->post('id') ?: suiji();
        $field      = [
            'category'  => $this->post('category'),
            'classify'  => $this->post('classify'),
            'subjectId' => $this->post('subjectId'),

        ];
        $annotation = [
            'category'  => '分类',
            'classify'  => '收支类别',
            'subjectId' => '科目',
        ];
        $rules      = [
            'category'  => 'required',
            'classify'  => 'required',
            'subjectId' => 'required',
        ];
        // 校验是否符合规则
        $vt     = new \verify();
        $result = $vt->setAliases($annotation)->validate($field, $rules)->isOk();
        if (!$this->power(self::page, "edit")) {
            $json['warn'] = "你没有" . self::title . "的编辑权限";
        } elseif ($result === false) {
            $json['warn'] = $vt->getErrs()[0];  // 多个规则提示最前面一条
        } elseif (static::total(array('table' => 'bookkeeping_setting', 'where' => "coid = '" . self::$coid . "' and classify = '$field[classify]' and subjectId = '$field[subjectId]' and id !='$id'")) > 0) {
            $json['warn'] = '已存在此配置';
        } else {
            $info = query('bookkeeping_setting', "id = '$id'");
            if (str_contains($field['classify'], '支-')) {
                $field['direction'] = '支出';
            } else {
                $field['direction'] = '收入';
            }
            if (empty($info['id'])) {
                $field        = array_merge($field, [
                    'id'   => $id,
                    'coid' => self::$coid,
                    'type' => '现金'
                ]);
                $json['warn'] = insert(array(
                    "table" => "bookkeeping_setting",
                    "field" => $field,
                ));

            } else {
                $json['warn'] = update(array(
                    "table" => "bookkeeping_setting",
                    "field" => $field,
                    "where" => "id = '$info[id]'",
                ));
            }

            if (in_array($json['warn'], ["新增成功", "更新成功"])) {
                //添加日志
                $type = mb_substr($json['warn'], 0, 2, 'utf-8');
                $text = $this->control['name'] . $type . "了" . self::title . "凭证配置，id：【" . $id . '】';
                $this->logText(["type" => self::page, "text" => $text]);
                //返回
                $_SESSION['warn'] = $json['warn'];
                $json['warn']     = 2;
                $json['href']     = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=setting";
            }
        }
        //返回
        return json_encode($json, 320);
    }

    /**
     * 导出
     */
    public function exportData()
    {
        if (!$this->power(self::page, 'export')) {
            $_SESSION['warn'] = '你还没有导出的权限';
        } else {
            $data      = [];
            $sql       = static::rGet(self::$stid . self::page . 'sql');
            $accountId = $this->getAccountRedis();
            $title     = ["日期", "摘要", "收支类别", "结算方式", "往来单位", "票据号", "备注", "收入（借方）", "支出（贷方）", "余额"];
            $result    = self::sqlFind($sql);
            if (is_array($result)) {
                foreach ($result as $array) {
                    $voucher     = query('voucher', "id = '$array[voucherId]'");
                    $voucherWord = query('voucher_word', "id = '$voucher[voucherWordId]'");
                    $account     = query('account', "id = '$array[accountId]'");
                    $balance     = find(array('table' => self::table, 'single' => "accountId = '$array[accountId]' and recordDate <='$array[recordDate]' and list <= $array[list]", 'field' => "ifnull(sum(income+expenses),0) as money"))['money'];
                    $balance     += $account['initMoney'];
                    $data[]      = [$array['recordDate'], $array['summary'], $array['classify'], $array['settleType'], $array['company'], $array['billNo'], $array['text'], $array['income'], $array['expenses'],
                        round($balance, 2), $voucherWord['word'] . '-' . $voucher['voucherNo']];
                }
            }
            $account = query('account', "id = '" . $accountId . "'");
            $text    = $this->control['name'] . "导出了账户【{$account['name']}】的现金日记账";
            $this->logText(["type" => self::page, "text" => $text]);
            $this->excelOut($title, $data, "【{$account['name']}】现金日记账.xlsx");
        }
        header("Location:" . getenv("HTTP_REFERER"));
        exit(0);
    }

    /**
     * 下载模板
     */
    public function downloadModel()
    {
        $templateId = $this->get('templateId');
        if (!$this->power(self::page, 'import')) {
            $_SESSION['warn'] = '你还没有导入的权限';
        } else {
            $exampleData[] = ['2022-01-01', '销售收入', '收-销售收入', '现结', '重庆雨木科技有限公司', '00001', '样例数据', '1000', ''];
            $excel    = $this->excelHead();
            $fileName = self::title.'导入模板-'.importTemplateClass::getName($templateId).'.xlsx';
            $filePath = $excel->fileName($fileName, 'sheet1');
            $format = new \Vtiful\Kernel\Format($filePath->getHandle());
            $templateField = importTemplateClass::templateField(self::page, 'importFieldInit', id:$templateId);
            $index         = 0;
            foreach ($templateField as $k => $array) {
                if ($array['display']){
                    $backgroundStyle=null;
                    if (importTemplateClass::getIsMustValue($this->importFieldInit(), $array['columnName'])){
                        //必填项判断
                        $backgroundStyle  = $format->background(
                            0xFFC04B
                        )->toResource();
                    }
                    $filePath->insertText(0, $index, $array['aliasName'],'',$backgroundStyle);
                    foreach ($exampleData as $y=>$example){
                        $exampleVal = match ($array['columnName']){
                            '日期'=>$example[0],
                            '摘要'=>$example[1],
                            '收支类别'=>$example[2],
                            '结算方式'=>$example[3],
                            '往来单位'=>$example[4],
                            '票据号'=>$example[5],
                            '备注'=>$example[6],
                            '收入'=>$example[7],
                            '支出'=>$example[8],
                            default=>'',
                        };
                        $filePath->insertText($y+1, $index, $exampleVal);
                    }
                    $index++;
                }
            }

            $text   = $this->control['name'] . "下载了现金日记账导入模板";
            $this->logText(["type" => self::page, "text" => $text]);
            $this->excelOutPut($filePath,$fileName);
            exit(0);
        }
        header("Location:" . getenv("HTTP_REFERER"));
    }

    /*数据导入分析*/
    public function importData()
    {
        $templateId = $this->post('templateId');
        if (!$this->power(self::page, 'import')) {
            $json['warn'] = '你还没有导入的权限';
        }  else {
             $fomatArray = [];//导入数据格式同一为TYPE_STRING
            foreach ($this->importFieldInit() as $value){
                $fomatArray[] = \Vtiful\Kernel\Excel::TYPE_STRING;
            }
            $data = $this->importHead(format: $fomatArray);
            $x    = 0;
            $text = '';
            $headArray = [];
            $row_list=0;
            foreach ($data as $i => $row) {
                $row_list++;
                if ($i==0){
                    $templateField = importTemplateClass::templateField(self::page, 'importFieldInit', id:$templateId);
                    $headArray = importTemplateClass::combinHead($templateField,$row);
                }
                if ($i > 0) {
                    $rowData = formSubArray($row);
                    //只接收模板中选中的字段的值
                    $cell = [];
                    foreach ($headArray as $index=>$headName){
                        $cell[$headName] = $rowData[$index]??'';
                    }
                    //初始化未被模板需要的字段的值
                    foreach ($this->importFieldInit() as $value){
                        $cell[$value['columnName']] = $cell[$value['columnName']]??'';
                    }

                    $field            = [
                        'id'         => suiji(),
                        'type'       => '现金',
                        'coid'       => self::$coid,
                        'stid'       => self::$stid,
                        'accountId'  => $this->getAccountRedis(),
                        'classify'   => $cell['收支类别'],
                        'recordDate' => self::importDateFormat($cell['日期']),
                        'company'    => $cell['往来单位'],
                        'summary'    => $cell['摘要'],
                        'income'     => $cell['收入'],
                        'expenses'   => $cell['支出'],
                        'settleType' => $cell['结算方式'],
                        'billNo'     => $cell['票据号'],
                        'text'       => $cell['备注'],
                    ];
                    $userNo           = codeTemplateClass::generateCode(self::page, [
                        'prefix' => date('Ymd'),
                        'table'  => self::table,
                        'field'  => 'orderNo',
                        'where'  => '',
                    ], $field);
                    $field['orderNo'] = $userNo;

                    $annotation = [
                        'accountId'  => '账户',
                        'classify'   => '收支类别',
                        'recordDate' => '日期',
                        'summary'    => '摘要',
                    ];
                    $rules      = [
                        'accountId'  => 'required',
                        'classify'   => 'required',
                        'recordDate' => 'required',
                        'summary'    => 'required',
                    ];
                    // 校验是否符合规则
                    $vt     = new \verify();
                    $result = $vt->setAliases($annotation)->validate($field, $rules)->isOk();
                    if ($result === false) {
                        $text .= "第【{$row_list}】行：" . $vt->getErrs()[0] . "<br>";  // 多个规则提示最前面一条
                    } elseif (empty($field['income']) && empty($field['expenses'])) {
                        $text .= "第【{$row_list}】行：请填写金额<br>";
                    } elseif (str_contains($field['classify'], '收-') && !empty($field['expenses'])) {
                        $text .= "第【{$row_list}】行：收支类型和金额不匹配<br>";
                    } elseif (str_contains($field['classify'], '支-') && !empty($field['income'])) {
                        $text .= "第【{$row_list}】行：收支类型和金额不匹配<br>";
                    } else {
                        $warn = insert(["table" => self::table, "field" => $field]);
                        if (in_array($warn, ["新增成功", "更新成功"])) {
                            $x++;
                            $text .= "第【{$row_list}】行：导入成功<br>";
                        } else {
                            $text .= "第【{$row_list}】行：导入失败：编辑失败<br>";
                        }
                    }
                }
            }
            $total = count($data)-1;
            $json['data'] = [
                'text'=>$text,
                'title'=>"您导入了{$total}条数据，成功{$x}条，失败".($total-$x)."条",
            ];
            $text = $this->control['name'] . '导入了文件：' . $_FILES['file']['name'] . '：' . $text;
            $this->logText(["type" => self::page, "text" => $text]);
            $json['warn'] = 2;
        }
        return json_encode($json,320);
    }


    // 操作中转
    public function operate()
    {
        $act  = $this->post('act') ?? '';
        $pwd  = false; // 需要密码
        $form = $power = $word = '';
        switch ($act) {
            case 'delSetting':
                $act      = 'del';
                $msg      = '删除' . self::title;
                $title    = self::page . 'DeleteSetting';
                $function = 'deleteSetting';
                $form     = self::page . 'OperateForm, visitForm';
                $power    = '';
                break;
            default:
                $act      = 'del';
                $msg      = '删除' . self::title;
                $title    = self::page . 'Delete';
                $function = 'delete';
                $form     = self::page . 'OperateForm, listForm';
                $power    = '';
                break;
        }
        if (!$this->power(self::page, $act)) {
            $_SESSION['warn'] = '你还没有' . $msg . '的权限';
            $json             = [
                'warn' => 2,
                'href' => root . 'control/adIndex.html?cla=' . $this->get('cla') . '&fun=home',
            ];
        } else {
            return $this->confirm([
                'title'    => $title,
                'function' => $function,
                'form'     => $form,
                'power'    => $power,
                'pwd'      => $pwd,
                'word'     => $word,
            ]);
        }

        resp:
        return json_encode($json, 320);
    }


    /**
     * 删除
     * @return bool|string
     */
    public function delete()
    {
        $array = $this->post('listId') ?? $this->post('id');
        if (!$this->power(self::page, "del")) {
            $json['warn'] = "你没有删除的权限";
        } elseif (empty($array)) {
            $json['warn'] = "你一个数据都没有选择呢";
        } else {
            $text  = "";
            $x     = 0;
            $array = is_array($array) ? $array : [$array];
            foreach ($array as $id) {
                $info = query(self::table, " id = '$id' ");
//                if ($info['state'] != '草稿') {
//                    $warn = "不是草稿状态，暂不能删除";
//                } else {
                //最后删除基本参数
                delete(array("table" => self::table, "where" => " id = '$id' "));
                //返回
                $warn = "删除成功";
                $x++;
//                }
                $text .= self::title . "ID【" . $info['id'] . "】" . $warn . "。<br>";
            }
            //添加日志
            $text = $this->control['name'] . "删除了" . self::title . "，结果如下：<br>" . $text;
            $this->logText(array("type" => self::page, "text" => $text));
            $_SESSION['warn'] = "删除了" . $x . "个" . self::title . "，详情见系统日志。";
            $json['warn']     = 2;
            $json['href']     = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=home";
        }
        return json_encode($json, 320);
    }

    /**
     * 删除凭证配置
     */
    public function deleteSetting()
    {
        $array = $this->post('listId') ?? $this->post('id');
        if (!$this->power(self::page, "del")) {
            $json['warn'] = "你没有删除的权限";
        } elseif (empty($array)) {
            $json['warn'] = "你一个数据都没有选择呢";
        } else {
            $text  = "";
            $x     = 0;
            $array = is_array($array) ? $array : [$array];
            foreach ($array as $id) {
                $info = query(self::table, " id = '$id' ");
//                if ($info['state'] != '草稿') {
//                    $warn = "不是草稿状态，暂不能删除";
//                } else {
                //最后删除基本参数
                delete(array("table" => 'bookkeeping_setting', "where" => " id = '$id' "));
                //返回
                $warn = "删除成功";
                $x++;
//                }
                $text .= "现金日记账凭证配置：ID【" . $info['id'] . "】" . $warn . "。<br>";
            }
            //添加日志
            $text = $this->control['name'] . "现金日记账凭证配置，结果如下：<br>" . $text;
            $this->logText(array("type" => self::page, "text" => $text));
            $_SESSION['warn'] = "删除了" . $x . "个" . self::title . "，详情见系统日志。";
            $json['warn']     = 2;
            $json['href']     = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=setting";
        }
        return json_encode($json, 320);
    }
    /**
     * 导入模板字段初始化
     * @return array[]
     */
    public function importFieldInit($classify=''): array
    {
        return match ($classify) {
            default=>  [
                [
                    'columnName'=>'日期',
                    'aliasName'=>'日期',

                    'isMust'=>true,
                ],
                [
                    'columnName'=>'摘要',
                    'aliasName'=>'摘要',

                    'isMust'=>true,
                ],
                [
                    'columnName'=>'收支类别',
                    'aliasName'=>'收支类别',

                    'isMust'=>true,
                ],
                [
                    'columnName'=>'结算方式',
                    'aliasName'=>'结算方式',

                    'isMust'=>false,
                ],
                [
                    'columnName'=>'往来单位',
                    'aliasName'=>'往来单位',

                    'isMust'=>false,
                ],
                [
                    'columnName'=>'票据号',
                    'aliasName'=>'票据号',

                    'isMust'=>false,
                ],
                [
                    'columnName'=>'备注',
                    'aliasName'=>'备注',

                    'isMust'=>false,
                ],
                [
                    'columnName'=>'收入',
                    'aliasName'=>'收入（借方）',

                    'isMust'=>false,
                ],
                [
                    'columnName'=>'支出',
                    'aliasName'=>'支出（贷方）',

                    'isMust'=>false,
                ],
            ]
        };
    }

}
